package com.dji.sample.map.controller;

import com.dji.sample.common.model.CustomClaim;
import com.dji.sample.component.websocket.service.IWebSocketMessageService;
import com.dji.sample.map.service.IWorkspaceElementService;
import com.dji.sdk.cloudapi.map.CreateMapElementRequest;
import com.dji.sdk.cloudapi.map.CreateMapElementResponse;
import com.dji.sdk.cloudapi.map.GetMapElementsResponse;
import com.dji.sdk.cloudapi.map.UpdateMapElementRequest;
import com.dji.sdk.cloudapi.map.api.IHttpMapService;
import com.dji.sdk.common.HttpResultResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;

import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;

/**
 * 工作空间元素控制器
 * 用于处理地图元素相关的HTTP请求，包括元素的增删改查操作
 * 实现了IHttpMapService接口定义的RESTful API
 */
@RestController
public class WorkspaceElementController implements IHttpMapService {

    @Autowired
    private IWorkspaceElementService elementService;

    @Autowired
    private IWebSocketMessageService sendMessageService;

    /**
     * 根据组ID删除该组内所有元素信息
     * 通过DELETE请求删除指定工作空间和组内的所有地图元素
     *
     * @param workspaceId 工作空间ID
     * @param groupId 组ID
     * @return HttpResultResponse 删除操作结果响应
     */
    @DeleteMapping("${url.map.prefix}${url.map.version}/workspaces/{workspace_id}/element-groups/{group_id}/elements")
    public HttpResultResponse deleteAllElementByGroupId(@PathVariable(name = "workspace_id") String workspaceId,
                                                        @PathVariable(name = "group_id") String groupId) {

        return elementService.deleteAllElementByGroupId(workspaceId, groupId);
    }

    /**
     * 获取地图元素列表
     * 在首次连接时，PILOT会发送此HTTP请求获取组元素列表
     * 如果PILOT从WebSocket接收到组刷新指令，也需要使用此接口重新请求组元素列表
     *
     * @param workspaceId 工作空间ID
     * @param groupId 组ID
     * @param isDistributed 是否已分发
     * @param req HTTP请求对象
     * @param rsp HTTP响应对象
     * @return HttpResultResponse<List<GetMapElementsResponse>> 地图元素列表响应
     */
    @Override
    public HttpResultResponse<List<GetMapElementsResponse>> getMapElements(String workspaceId, String groupId, Boolean isDistributed, HttpServletRequest req, HttpServletResponse rsp) {
        List<GetMapElementsResponse> groupsList = elementService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed);
        return HttpResultResponse.<List<GetMapElementsResponse>>success(groupsList);
    }

    /**
     * 创建地图元素
     * 当用户在PILOT/Web端绘制点、线或面时，将元素信息保存到数据库
     *
     * @param workspaceId 工作空间ID
     * @param groupId 组ID
     * @param elementCreate 地图元素创建请求对象，包含元素的详细信息
     * @param req HTTP请求对象
     * @param rsp HTTP响应对象
     * @return HttpResultResponse<CreateMapElementResponse> 创建元素响应结果
     */
    @Override
    public HttpResultResponse<CreateMapElementResponse> createMapElement(String workspaceId, String groupId,
                                                                         @Valid CreateMapElementRequest elementCreate, HttpServletRequest req, HttpServletResponse rsp) {
        CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM);
        // 设置元素的创建者
        elementCreate.getResource().setUsername(claims.getUsername());

        HttpResultResponse response = elementService.saveElement(workspaceId, groupId, elementCreate, true);
        if (response.getCode() != HttpResultResponse.CODE_SUCCESS) {
            return response;
        }

        return HttpResultResponse.success(new CreateMapElementResponse().setId(elementCreate.getId()));
    }

    /**
     * 更新地图元素
     * 当用户在PILOT/Web端编辑点、线或面时，更新数据库中的元素信息
     *
     * @param workspaceId 工作空间ID
     * @param elementId 元素ID
     * @param elementUpdate 地图元素更新请求对象，包含更新后的元素信息
     * @param req HTTP请求对象
     * @param rsp HTTP响应对象
     * @return HttpResultResponse 更新元素操作结果响应
     */
    @Override
    public HttpResultResponse updateMapElement(String workspaceId, String elementId, @Valid UpdateMapElementRequest elementUpdate, HttpServletRequest req, HttpServletResponse rsp) {
        CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM);

        HttpResultResponse response = elementService.updateElement(workspaceId, elementId, elementUpdate, claims.getUsername(), true);
        if (response.getCode() != HttpResultResponse.CODE_SUCCESS) {
            return response;
        }

        return response;
    }

    /**
     * 删除地图元素
     * 当用户在PILOT/Web端删除点、线或面时，删除数据库中的元素信息
     *
     * @param workspaceId 工作空间ID
     * @param elementId 元素ID
     * @param req HTTP请求对象
     * @param rsp HTTP响应对象
     * @return HttpResultResponse 删除元素操作结果响应
     */
    @Override
    public HttpResultResponse deleteMapElement(String workspaceId, String elementId, HttpServletRequest req, HttpServletResponse rsp) {

        return elementService.deleteElement(workspaceId, elementId, true);
    }
}